//#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LEN sizeof(struct student)
#define FORMAT "\t%d\t%s\t%.1lf\t%.1lf\t%.1lf\t%.1lf\n"
#define ELEMENT stu[i].num,stu[i].name,stu[i].language,stu[i].math,stu[i].cprogram,stu[i].sum
#define FILENAME "stuscore.txt"

struct student { 
    int num;        
    char name[15];    
    double language;    
    double math;    
    double cprogram;    
    double sum;        
};

struct student stu[50];    /*@改进@ 判断超出数组上界*/

void add();                //录入学生成
void show();            //显示学生成绩
void del();                //删除学生成绩
void modify();            //修改学生成绩
void menu();            //主菜单
void insert();            //插入学生成绩
void search();            //查找学生成绩

int main() { 
    int n = -1;  // Initialize with a value not equal to 0
    while (n != 0) {  // This creates a loop that continues until the user enters 0 to exit
        menu();  // Display the menu
        scanf("%d", &n);  // Get user input for the action

        switch (n) {
            case 0:
                printf("\t退出系统。\n");
                break;
            case 1:
                add();
                break;
            case 2:
                search();
                break;
            case 3:
                del();
                break;
            case 4:
                modify();
                break;
            case 5:
                insert();
                break;
            case 6:
                show();
                break;
            default:
                printf("\t请输入数字0-6，按任意键返回重新输入。\n");
                break;
        }

        if (n != 0) {
            printf("\n\t按任意键返回主界面...");
            getchar();  // Replace getch() with getchar()
        }
    }

    printf("\n\t感谢使用学生成绩管理系统！\n");
    return 0;
}

void add() { 
    int i, m = 0;  // m是记录的条数
    char ch[2];
    FILE *fp;
    if ((fp = fopen(FILENAME, "r+")) == NULL) { // 打开指定文件
        printf("文件不存在，请先录入学生成绩信息！\n");
        return;
    }
    while (!feof(fp)) {
        if (fread(&stu[m], LEN, 1, fp) == 1) 
            m++;
        if (m >= 50) { // @改进@ 判断是否超出数组上界
            printf("学生记录已满，无法添加更多！\n");
            fclose(fp);
            return;
        }
    }
    if (m == 0) {
        printf("当前还没有学生成绩信息！\n");
    }
    printf("\t是否需要录入(Y/N，不区分大小写):");
    scanf("%s", ch);
    while (ch[0] == 'Y' || ch[0] == 'y') {
        system("cls"); 
        printf("\n");
        printf("\t请录入学生成绩信息\n");
        printf("\t学号:");
        scanf("%d", &stu[m].num);
        for (i = 0; i < m; i++) {
            if (stu[i].num == stu[m].num) {
                printf("\t学号已存在，请重新输入！\n");
                return;
            }
        }
        printf("\t姓名:");
        scanf("%s", stu[m].name);
        printf("\t语文:");
        scanf("%lf", &stu[m].language);
        printf("\t数学:");
        scanf("%lf", &stu[m].math);
        printf("\tC语言:");
        scanf("%lf", &stu[m].cprogram);
        stu[m].sum = stu[m].language + stu[m].math + stu[m].cprogram;  //计算总成绩
        if (fwrite(&stu[m], LEN, 1, fp) != 1) {
            printf("不能保存!\n");
            getchar();
        } else {
            printf("\t%s 成绩信息已保存!\n", stu[m].name);
            m++;
        }
        printf("\n");
        printf("\t是否继续录入？(Y/N):");
        scanf("%c", ch);
    }
    fclose(fp);
    printf("\n\t不录入学生成绩信息，按任意键返回主界面...\n");
}

void show() { 
    FILE *fp;
    int i, m = 0;
    if ((fp = fopen(FILENAME, "r")) == NULL) { 
        printf("文件不存在，请先录入学生成绩信息！\n");
        return;
    } 
    while (!feof(fp)) {
        if (fread(&stu[m], LEN, 1, fp) == 1) 
            m++;
        if (m >= 50) { // @改进@ 判断越界
            printf("学生记录已满，无法显示更多！\n");
            break;
        }
    }
    if (m == 0) {
        printf("当前还没有学生成绩信息！\n");
        return;
    }
    printf("\n\t一共有 %d 名学生！\n", m);
    printf("\t|――――――――学生成绩信息――――――――|\n");
    printf("\t学号\t姓名\t语文\t数学\tC语言\t总分\t\n");
    for (i = 0; i < m; i++) { 
        printf(FORMAT, ELEMENT);
    }
    printf("\n");
    fclose(fp);
}

void menu() { 
    system("cls");  //清屏
    printf("\n\n\n");
    printf("\t|――――――――学生成绩管理系统――――――――|\n");
    printf("\t|\t\t\t\t\t |\n");
    printf("\t|\t\t  1.录入学生成绩\t         |\n");
    printf("\t|\t\t  2.查找学生成绩\t         |\n");
    printf("\t|\t\t  3.删除学生成绩\t         |\n");
    printf("\t|\t\t  4.修改学生成绩\t         |\n");
    printf("\t|\t\t  5.插入学生成绩\t         |\n");
    printf("\t|\t\t  6.显示学生成绩\t\t |\n");
    printf("\t|\t\t  0.退出系统\t\t         |\n");
    printf("\t|\t\t\t\t\t |\n");
    printf("\t|――――――――――――――――――――――――|\n\n");
    printf("\t\t请输入菜单编号(0-6):");
}

void del() { 
    FILE *fp;
    int snum, i, m = 0;
    char ch[2];
    if ((fp = fopen(FILENAME, "r+")) == NULL) { 
        printf("文件不存在，请先录入学生成绩信息！\n");
        return;
    }
    while (!feof(fp)) {
        if (fread(&stu[m], LEN, 1, fp) == 1) 
            m++;
        if (m >= 50) {
            printf("学生记录已满，无法删除！\n");
            break;
        }
    }
    if (m == 0) { 
        printf("文件中没有记录！\n");
        return;
    }
    system("cls");
    show();
    printf("\t请输入学生学号：");
    scanf("%d", &snum); 
    for (i = 0; i < m; i++) {  
        if (snum == stu[i].num) {           
            printf("\t找到了，是否删除?(Y/N)：");
            scanf("%s", ch);
            if (ch[0] == 'Y' || ch[0] == 'y') {  //需要删除
                for (int j = i; j < m - 1; j++) {
                    stu[j] = stu[j + 1];  // @实现@ 删除记录
                }
                m--;
                if ((fp = fopen(FILENAME, "wb")) == NULL) { 
                    printf("文件不存在\n");
                    return;
                }
                for (i = 0; i < m; i++) { 
                    fwrite(&stu[i], LEN, 1, fp);  //写回文件
                }
                fclose(fp);
                printf("\t删除成功!\n");
                printf("\n\t按任意键返回主界面...\n");
                return;
            } else {
                printf("\t选择不删除！\n");
                printf("\n\t按任意键返回主界面...\n");
                return;
            }
        }
    }
    printf("\t没有找到这名学生!\n");
    printf("\n\t按任意键返回主界面...\n");  
}

void search() { 
    FILE *fp;
    int snum, i, m = 0;
    if ((fp = fopen(FILENAME, "r+")) == NULL) { 
        printf("文件不存在，请先录入学生成绩信息！\n");
        return;
    }
    while (!feof(fp)) {
        if (fread(&stu[m], LEN, 1, fp) == 1) 
            m++;
    }
    if (m == 0) { 
        printf("文件中没有记录！\n");
        return;
    }
    system("cls");
    printf("\n");
    printf("\t请输入要查找学生的学号:");
    scanf("%d", &snum);
    for (i = 0; i < m; i++) { 
        if (stu[i].num == snum) {
            printf("\t找到了，学生成绩信息：\n");
            printf(FORMAT, ELEMENT);
            fclose(fp);
            printf("\n\t按任意键返回主界面...\n");
            return;
        }
    }
    printf("\t没有找到学生成绩！\n");
    fclose(fp);
    printf("\n\t按任意键返回主界面...\n");
}

void modify() { 
    FILE *fp;
    struct student t;
    int i = 0, j = 0, m = 0, snum;
    if ((fp = fopen(FILENAME, "r+")) == NULL) { 
        printf("文件不存在，请先录入学生成绩信息！\n");
        return;
    }
    while (!feof(fp)) {
        if (fread(&stu[m], LEN, 1, fp) == 1) 
            m++;
    }
    if (m == 0) { 
        printf("文件中没有记录！\n");
        return;
    }
    system("cls");
    show();
    printf("\t请输入要修改的学号：");
    scanf("%d", &snum);
    for (i = 0; i < m; i++) { 
        if (stu[i].num == snum) { 
            printf("\t找到了，请录入新的成绩信息！\n");     
            printf("\t姓名：");
            scanf("%s", stu[i].name);
            printf("\t语文：");
            scanf("%lf", &stu[i].language);
            printf("\t数学：");
            scanf("%lf", &stu[i].math);
            printf("\tC语言：");
            scanf("%lf", &stu[i].cprogram);
            stu[i].sum = stu[i].language + stu[i].math + stu[i].cprogram; 
            if ((fp = fopen(FILENAME, "wb")) == NULL) { 
                printf("不能打开文件！\n");
                return;
            }
            for (j = 0; j < m; j++) { 
                fwrite(&stu[j], LEN, 1, fp);
            }
            fclose(fp);
            printf("\t修改成功!");
            show();  //显示修改后的信息
            printf("\n\t按任意键返回主界面...\n");
            break;
        }
    }
    if (i == m) { 
        printf("\t没有找到学生成绩信息！\n");
    }
}

void insert() { 
    FILE *fp;
    int i, j, k, m = 0, n, snum;
    if ((fp = fopen(FILENAME, "r+")) == NULL) { 
        printf("文件不存在，请先录入学生成绩信息！\n");
        return;
    }
    while (!feof(fp)) {
        if (fread(&stu[m], LEN, 1, fp) == 1) 
            m++;
        if (m >= 50) { 
            printf("学生记录已满，无法插入更多！\n");
            break;
        }
    }
    if (m == 0) { 
        printf("文件中没有记录!\n");
        return;
    }
    system("cls");
    show();
    printf("\t请输入要插入的位置：");
    scanf("%d", &n);  // 要插入的位置
    if (n < 1 || n > m) {  // @改进@ 判断位置越界
        printf("插入位置不合法！\n");
        return;
    }
    for (i = m; i >= n; i--) {
        stu[i] = stu[i - 1];  // @实现@ 依次向后移1位
    }
    printf("\t请录入学生成绩信息\n");
    printf("\t学号：");
    scanf("%d", &snum);
    for (k = 0; k < m; k++) {
        if (stu[k].num == snum) {
            printf("\t学号已存在，按任意键继续!\n");
            getchar();
            fclose(fp);
            return;
        }
    }
    stu[n - 1].num = snum;
    printf("\t姓名：");
    scanf("%s", stu[n - 1].name);
    printf("\t语文：");
    scanf("%lf", &stu[n - 1].language);
    printf("\t数学：");
    scanf("%lf", &stu[n - 1].math);
    printf("\tC语言：");
    scanf("%lf", &stu[n - 1].cprogram);
    stu[n - 1].sum = stu[n - 1].language + stu[n - 1].math + stu[n - 1].cprogram;
    if ((fp = fopen(FILENAME, "wb")) == NULL) {
        printf("不能保存!\n");
        return;
    }
    for (k = 0; k <= m; k++) { 
        fwrite(&stu[k], LEN, 1, fp);
    }
    fclose(fp);
    printf("\t插入成功，按任意键返回主界面！\n");
}
